﻿using DDE_Server.Event;
using NDde.Server;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;

namespace DDE_Server.Object
{
   
    public class MyServer : DdeServer
    {
        //private System.Timers.Timer _Timer = new System.Timers.Timer();
        private List<DataEntry> dataList = null;
        public MyServer(string service)
            : base(service)
        {
            // Create a timer that will be used to advise clients of new data.
            //_Timer.Elapsed += this.OnTimerElapsed;
            //_Timer.Interval = 1000;
            //_Timer.SynchronizingObject = this.Context;
        }

        public void AdviseData(object sender, DataChangedEventArgs e)
        {
            dataList = e.dataList;
            // Advise all topic name and item name pairs.
            Advise("*", "*");
        }
        private void OnTimerElapsed(object sender, ElapsedEventArgs args)
        {
            // Advise all topic name and item name pairs.
            Advise("*", "*");
        }

        public override void Register()
        {
            //_Timer.Start();
            base.Register();
        }

        public override void Unregister()
        {
            //_Timer.Stop();
            base.Unregister();
        }

        protected override bool OnBeforeConnect(string topic)
        {
            //Console.WriteLine("OnBeforeConnect:".PadRight(16)
            //    + " Service='" + base.Service + "'"
            //    + " Topic='" + topic + "'");
            Advise("*", "*");
            return true;
        }

        protected override void OnAfterConnect(DdeConversation conversation)
        {
            //Console.WriteLine("OnAfterConnect:".PadRight(16)
            //    + " Service='" + conversation.Service + "'"
            //    + " Topic='" + conversation.Topic + "'"
            //    + " Handle=" + conversation.Handle.ToString());
        }

        protected override void OnDisconnect(DdeConversation conversation)
        {
            //Console.WriteLine("OnDisconnect:".PadRight(16)
            //    + " Service='" + conversation.Service + "'"
            //    + " Topic='" + conversation.Topic + "'"
            //    + " Handle=" + conversation.Handle.ToString());
        }

        protected override bool OnStartAdvise(DdeConversation conversation, string item, int format)
        {
            //Console.WriteLine("OnStartAdvise:".PadRight(16)
            //    + " Service='" + conversation.Service + "'"
            //    + " Topic='" + conversation.Topic + "'"
            //    + " Handle=" + conversation.Handle.ToString()
            //    + " Item='" + item + "'"
            //    + " Format=" + format.ToString());

            // Initiate the advisory loop only if the format is CF_TEXT.
            return format == 1;
        }

        protected override void OnStopAdvise(DdeConversation conversation, string item)
        {
            //Console.WriteLine("OnStopAdvise:".PadRight(16)
            //    + " Service='" + conversation.Service + "'"
            //    + " Topic='" + conversation.Topic + "'"
            //    + " Handle=" + conversation.Handle.ToString()
            //    + " Item='" + item + "'");
        }

        protected override ExecuteResult OnExecute(DdeConversation conversation, string command)
        {
            //Console.WriteLine("OnExecute:".PadRight(16)
            //    + " Service='" + conversation.Service + "'"
            //    + " Topic='" + conversation.Topic + "'"
            //    + " Handle=" + conversation.Handle.ToString()
            //    + " Command='" + command + "'");

            // Tell the client that the command was processed.
            return ExecuteResult.Processed;
        }

        protected override PokeResult OnPoke(DdeConversation conversation, string item, byte[] data, int format)
        {
            //Console.WriteLine("OnPoke:".PadRight(16)
            //    + " Service='" + conversation.Service + "'"
            //    + " Topic='" + conversation.Topic + "'"
            //    + " Handle=" + conversation.Handle.ToString()
            //    + " Item='" + item + "'"
            //    + " Data=" + data.Length.ToString()
            //    + " Format=" + format.ToString());

            // Tell the client that the data was processed.
            return PokeResult.Processed;
        }

        protected override RequestResult OnRequest(DdeConversation conversation, string item, int format)
        {
            //Console.WriteLine("OnRequest:".PadRight(16)
            //    + " Service='" + conversation.Service + "'"
            //    + " Topic='" + conversation.Topic + "'"
            //    + " Handle=" + conversation.Handle.ToString()
            //    + " Item='" + item + "'"
            //    + " Format=" + format.ToString());

            // Return data to the client only if the format is CF_TEXT.
            String name = conversation.Topic;
            IEnumerable<DataEntry> ret = dataList;
            if (dataList != null && format == 1)
            {
                ret = ret.Where(ent => ent.StripName == name);

                List<DataEntry> entrys = ret.ToList();
                if (entrys.Count == 1)
                {
                    switch (item)
                    {
                        case "bidActive":
                            return new RequestResult(
                                System.Text.Encoding.ASCII.GetBytes(entrys[0].Status));
                        case "offerActive":
                            return new RequestResult(
                                System.Text.Encoding.ASCII.GetBytes(entrys[0].BidOffer));
                        case "bidOfferPrice":
                            return new RequestResult(
                                System.Text.Encoding.ASCII.GetBytes(entrys[0].Price));
                        case "timer":
                            return new RequestResult(
                                System.Text.Encoding.ASCII.GetBytes(entrys[0].timer.ToString()));
                    }
                }
                else
                {
                    if (entrys.Count == 0)
                        return new RequestResult(System.Text.Encoding.ASCII.GetBytes("No Name Match"));
                    else
                        return new RequestResult(System.Text.Encoding.ASCII.GetBytes("More than one name in list"));
                }
            }
            return RequestResult.NotProcessed;
        }

        protected override byte[] OnAdvise(string topic, string item, int format)
        {
            
            String name = topic;
            IEnumerable<DataEntry> ret = dataList;
            if (dataList != null && format == 1)
            {
                ret = ret.Where(ent => ent.StripName == name);

                List<DataEntry> entrys = ret.ToList();
                if (entrys.Count == 1)
                {
                    switch (item)
                    {
                        case "bidActive":
                            return 
                                System.Text.Encoding.ASCII.GetBytes(entrys[0].Status);
                        case "offerActive":
                            return 
                                System.Text.Encoding.ASCII.GetBytes(entrys[0].BidOffer);
                        case "bidOfferPrice":
                            return 
                                System.Text.Encoding.ASCII.GetBytes(entrys[0].Price);
                        case "timer":
                            return 
                                System.Text.Encoding.ASCII.GetBytes(entrys[0].timer.ToString());
                    }
                }
                else
                {
                    if (entrys.Count == 0)
                        return System.Text.Encoding.ASCII.GetBytes("No Name Match");
                    else
                        return System.Text.Encoding.ASCII.GetBytes("More than one name in list");
                }
            }

            return null;
        }
    }
}
